package org.lc.ktsdb.dsl

import kotlinx.coroutines.runBlocking
import kotlin.script.experimental.annotations.KotlinScript
import kotlin.script.experimental.api.*
import kotlin.script.experimental.dependencies.*
import kotlin.script.experimental.dependencies.maven.MavenDependenciesResolver
import kotlin.script.experimental.jvm.JvmDependency
import kotlin.script.experimental.jvm.dependenciesFromCurrentContext
import kotlin.script.experimental.jvm.jvm

@KotlinScript(
    fileExtension = "db.kts",
    compilationConfiguration = DemoScriptDepsConfiguration::class
)
abstract class DemoScriptDeps

object DemoScriptDepsConfiguration: ScriptCompilationConfiguration({
    // 此类型的所有脚本的隐式导入
    defaultImports(DependsOn::class, Repository::class)
    jvm {
        // 从上下文类加载器中提取整个类路径并将其用作依赖项
        dependenciesFromCurrentContext(wholeClasspath = true)
    }
    // Callbacks
    refineConfiguration {
        // 从上下文类加载器中提取整个类路径并将其用作依赖项
        onAnnotations(DependsOn::class, Repository::class, handler = ::configureMavenDepsOnAnnotations)
    }
})

private val resolver = CompoundDependenciesResolver(FileSystemDependenciesResolver(), MavenDependenciesResolver())

// 在脚本编译期间调用的处理程序，以便动态重新配置编译
fun configureMavenDepsOnAnnotations(context: ScriptConfigurationRefinementContext): ResultWithDiagnostics<ScriptCompilationConfiguration> {
    val annotations = context.collectedData?.get(ScriptCollectedData.collectedAnnotations)?.takeIf { it.isNotEmpty() }
        ?: return context.compilationConfiguration.asSuccess() // If no action is performed, the original configuration should be returned
    return runBlocking {
        // 使用注解参数解析maven工件
        resolver.resolveFromScriptSourceAnnotations(annotations)
    }.onSuccess {
        context.compilationConfiguration.with {
            // 使用新解析的工件作为编译依赖项更新原始配置
            dependencies.append(JvmDependency(it))
        }.asSuccess()
    }
}
